import java.io.IOException;
import java.util.Comparator;
import java.util.HashSet;

public class Author {
  public static int VERY_HIGH_DATE = 50000000;
  String firstName_;
  String lastName_;
  String name_;
  
  int dateStamp_;
  String dateStampStr_;
  int author_id_;
  
  HashSet<Integer> neighbors_;
  int degree_;
  
  public static class AuthorDateComparator implements Comparator<Author>{
    public int compare(Author a1, Author a2) {
      return a1.getDateStamp() - a2.getDateStamp(); 
    }
  }
  
  public static class AuthorDegreeComparator implements Comparator<Author> {
    public int compare(Author a1, Author a2) {
      return a2.getDegree() - a1.getDegree();
    }
  }
  
  public Author(int id, String name) throws IOException {
    author_id_ = id;
    dateStamp_ = VERY_HIGH_DATE;
    
    name_ = name;
    String[] toks = name_.split(", ");
    if (toks.length != 2) {
      throw new IOException("Name: " + name_ + "is not parsable.");
    }
    
    firstName_ = toks[0];
    lastName_ = toks[1];
    
    neighbors_ = new HashSet<Integer>();
    degree_ = 0;
  }
  
  public int getAuthorId() {
    return author_id_;
  }
  
  public static String calculateAuthorName(String firstName, String lastName) {
    return (lastName + ", " + normalize(firstName)).toUpperCase();
  }
  
  public static String normalize(String orig) {
    String[] toks = orig.split(" ");
    String res = "";
    
    for (int i = 0; i < toks.length; ++i) {
      if (toks[i].endsWith(".")) {
        res = res + toks[i];
      } else {
        res = res + toks[i].charAt(0) + '.';
      }
    }
    
    return res;
  }
  
  public static Integer DateToInteger(String dateStamp) throws IOException {
    String[] toks = dateStamp.split("-");

    if (toks.length != 3) {
      throw new IOException("Invalid datestamp format: " + dateStamp);
    }
    
    int year, month, date;
    year = Integer.parseInt(toks[0]);
    month = Integer.parseInt(toks[1]);
    date = Integer.parseInt(toks[2]);
    
    return (date + month * 100 + year * 10000);    
  }
  
  public String getName() {
    return name_;
  }

  public String getFirstName() {
    return firstName_;
  }

  public void setFirstName(String firstName) {
    this.firstName_ = firstName;
  }

  public String getLastName() {
    return lastName_;
  }

  public void setLastName(String lastName) {
    this.lastName_ = lastName;
  }

  public int getDateStamp() {
    return dateStamp_;
  }
  
  public String getDateStampStr() {
    return dateStampStr_;
  }
  
  public void setDateStamp(int ts) {
    dateStamp_ = ts;
  }

  public void updateDateStamp(String dateStamp) throws IOException {
    int newts = DateToInteger(dateStamp);
    
    if (newts < dateStamp_) {
      dateStamp_ = newts;
      dateStampStr_ = new String(dateStamp);
    }
  }
  
  public boolean isValid() {
    return (dateStamp_ != VERY_HIGH_DATE);
  }

  public String toString() {
    return "[" + author_id_ + "] " + " " + degree_ + " " + name_ + " : " + dateStampStr_;
  }
  
  public void addNeighbor(Integer n_id) {
    if (n_id.equals(author_id_)) return;

    if (!neighbors_.contains(n_id)) {
      neighbors_.add(n_id);
      degree_++;
    }
  }

  public int getDegree() {
    return degree_;
  }
}
